package com.example.demo;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName: PrintAbcDemo_2
 * @Description: 在demo1的基础上完成性能改造。
 * @Author:
 * @Date
 */
public class PrintAbcDemo_2 {
    private int singal = 0;
    Lock lock = new ReentrantLock();
    Condition a = lock.newCondition();
    Condition b = lock.newCondition();
    Condition c = lock.newCondition();

    public void printA() throws InterruptedException {
        lock.lock();
        while (singal != 0) {
            a.await();
        }
        singal ++;
        System.out.println("A");
        b.signal();
        lock.unlock();
        Thread.sleep(1000);
    }

    public void printB() throws InterruptedException {
        lock.lock();
        while (singal != 1) {
            b.await();
        }
        singal ++;
        System.out.println("b");
        c.signal();
        lock.unlock();
        Thread.sleep(1000);
    }

    public void printC() throws InterruptedException {
        lock.lock();
        while (singal != 2) {
            c.await();
        }
        singal = 0;
        System.out.println("c");
        a.signal();
        lock.unlock();
        Thread.sleep(1000);
    }

    public static void main(String[] args) {
        PrintAbcDemo_2 printAbcDemo_2 = new PrintAbcDemo_2();
        Thread printAThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        printAbcDemo_2.printA();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        printAThread.start();

        Thread printBThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        printAbcDemo_2.printB();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        printBThread.start();

        Thread printCThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        printAbcDemo_2.printC();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        printCThread.start();
    }
}

